package game;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.util.Set;

public class Controller implements IGameEventListener, IGUIEventListener {

	private static Controller singleton = null;

	private Controller() {
	}

	public static Controller Get() {
		if (singleton == null)
			singleton = new Controller();
		return singleton;
	}

	private GameGUI gui = new GameGUI(this, Game.GetGameList());
	private Game currentGame;

	// fields about target selecting
	private boolean waitingTarget = false;
	private Point lastLocation = null;

	// fields about message
	private String tieMessage = "Tie!!";
	private String cancelMessage = "Target selection is canceled!";

	// fields about game state
	private int currentPlayerID = 0;

	public void run() {
		gui.Run();
	}

	@Override
	public void OnGameSelected(String name) {
		//System.out.println("OnGameSelected");
		assert Game.GetGameList().contains(name);
		currentGame = Game.GetGame(name, this);
		currentGame.Init();
		gui.InitBoard(currentGame.GetBoardSize());
	}

	@Override
	public void OnLocationSelected(Point location) {
		////System.out.println("OnLocationSelected");
		assert currentGame != null;
		if (waitingTarget == true) {
			assert currentGame.GetValidTargets(lastLocation).contains(location);
			currentGame.Action(lastLocation, location);
			waitingTarget = false;
			gui.SetBoardEnable(true);
		} else if (currentGame.IsActionableWithoutTarget(location)) {
			currentGame.Action(location);
		} else {
			waitingTarget = true;
			lastLocation = location;
			gui.SetBoardEnable(false);
			this.enableTargets(currentGame.GetValidTargets(lastLocation));
		}
	}

	@Override
	public void OnTie() {
		//System.out.println("OnTie");
		gui.SetBoardEnable(false);
		gui.SetDialogMessage(tieMessage);
	}

	@Override
	public void OnCancel() {
		//System.out.println("OnCancel");
		waitingTarget = false;
		gui.SetMessage(cancelMessage);
		gui.SetBoardEnable(true);
	}

	@Override
	public void OnGameOver() {
		//System.out.println("OnGameOver");
		gui.SetBoardEnable(false);
		gui.SetDialogMessage("Winner is:Player" + (currentPlayerID + 1));
		gui.Run();
	}

	@Override
	public void OnPlayerChange() {
		//System.out.println("OnPlayerChange");
		currentPlayerID = currentGame.GetCurrentPlayer();
		gui.SetCurrentPlayerByID(currentPlayerID);
	}

	@Override
	public void OnPlayerColorChange(int playerID, Color color) {
		//System.out.println("OnPlayerColorChange");
		gui.SetPlayerColor(playerID, color);
	}

	@Override
	public void OnPaint(Graphics g, Point size, Point location) {
		//System.out.println("OnPaint");
		this.currentGame.PaintLocation(g, size, location);
	}

	private void enableTargets(Set<Point> targets) {
		gui.SetBoardEnable(false);
		for (Point target : targets) {
			gui.SetLocationEnable(target, true);
		}
	}

}
